
修好 LSTM forward執行圖
“你永遠不會忘記第一次看到 NotImplementedError。”
今天的任務很簡單:
我想讓我的 LSTM 模型學會一件小事——
看到 [1,2,3,4] → 預測 [2,3,4,5]。
沒想到我卻被一句錯誤訊息卡了一整天:
NotImplementedError: Module [LSTMModel] is missing the required "forward" function
Debug 是最好的老師這次錯誤雖然只是個縮排問題,但卻讓我更理解 PyTorch 的設計邏輯:每個模型都是一個類別,而「forward()」是它的思考過程。
當我們能掌握這層抽象邏輯後,不論是要接 CNN、RNN、Transformer,都會從從容容,游刃有餘。
我的原始程式長這樣:
class LSTMModel(nn.Module):
def __init__(self, input_size=1, hidden_size=32, num_layers=1, output_size=1):
super(LSTMModel, self).__init__()
self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
out, _ = self.lstm(x)
out = self.fc(out)
return out
看起來沒問題對吧?但 PyTorch 報錯說「我沒有 forward()」,結果真相其實非常細節:就是我把 forward() 縮排到 init 裡面去了!這代表這個函式只存在於 init 的作用域中,而不是屬於這個類別(class)的方法,對 Python 來說,這段根本就像不存在一樣。
修正只要一行!
把 forward() 往左退一格,
跟 init 平行就好👇
import torch
import torch.nn as nn
import torch.optim as optim
# 模型定義
class LSTMModel(nn.Module):
def __init__(self, input_size=1, hidden_size=32, num_layers=1, output_size=1):
super(LSTMModel, self).__init__()
self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
# ✅ 正確縮排:讓 forward 成為類別方法
def forward(self, x):
out, _ = self.lstm(x)
out = self.fc(out)
return out
小型實驗:LSTM 學會「數數」
下面是完整可執行的範例。它會讓模型從 [1,2,3,4] 學會輸出 [2,3,4,5]。
# 建立資料
x = torch.tensor([[1,2,3,4]], dtype=torch.float32).unsqueeze(-1)
y = torch.tensor([[2,3,4,5]], dtype=torch.float32).unsqueeze(-1)
# 初始化
model = LSTMModel()
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)
# 訓練
for epoch in range(200):
optimizer.zero_grad()
output = model(x)
loss = criterion(output, y)
loss.backward()
optimizer.step()
if (epoch+1) % 20 == 0:
print(f"Epoch [{epoch+1}/200], Loss: {loss.item():.6f}")
# 測試
test_input = torch.tensor([[2,3,4,5]], dtype=torch.float32).unsqueeze(-1)
pred = model(test_input).detach().numpy()
print("\nInput:", test_input.view(-1).tolist())
print("Predicted:", pred.round(2).reshape(-1).tolist())
✅ 執行結果
Epoch [20/200], Loss: 0.032101
Epoch [40/200], Loss: 0.000823
...
Input: [2.0, 3.0, 4.0, 5.0]
Predicted: [3.0, 4.0, 5.0, 6.0]
模型成功學會了「加一的規律」!也代表我們的 LSTM 實作路終於跑通了恭喜賀喜!!